<?php
/**
 * Created by PhpStorm.
 * User: 我型我素
 * Date: 2018/1/18
 * Time: 17:31
 */

namespace App\Services\Goods;


use App\Repositories\Goods\GoodsBookRepository;
use App\Repositories\Goods\GoodsPresellTimeRepository;
use App\Repositories\Goods\GoodsRepository;
use App\Repositories\Users\UsersRepository;
use App\Services\Common\BaseService;
use App\Services\PromoteService;
use Illuminate\Support\Facades\Cache;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

class GoodsService extends BaseService
{

    /**
     * @var GoodsRepository
     */
    protected $goodsRepository;

    /**
     * @var
     */
    protected $goodsPresellTimeRepository;

    /**
     * @var GoodsBookRepository
     */
    protected $goodsBookRepository;

    protected $usersRepository;

    /**
     * @var PromoteService
     */
    protected $promoteService;


    public function __construct(GoodsRepository $goodsRepository,
                                GoodsPresellTimeRepository $goodsPresellTimeRepository,
                                GoodsBookRepository $goodsBookRepository,
                                UsersRepository $usersRepository,
                                PromoteService $promoteService)
    {
        $this->goodsRepository = $goodsRepository;

        $this->goodsPresellTimeRepository = $goodsPresellTimeRepository;

        $this->goodsBookRepository = $goodsBookRepository;

        $this->usersRepository = $usersRepository;

        $this->promoteService = $promoteService;
    }

    /**
     * 队列检查订单商品库存
     * @author yangzhic
     * @param $param
     */
    public function checkQueueOrderGoodsStock($param)
    {
        $current_date=date('Y-m-d',time());
        $best_time_date=date('Y-m-d',$param['best_time']);
        $is_tomorrow=0;//是否次日送达，若是，则1
        if($current_date!=$best_time_date){
            $is_tomorrow=1;
        }

        $out_stock_goods = array();

        $goods_list = $param['goods_list'];
        $wid = $param['wid'];

        if(!empty($goods_list)){
            $goods_in_stock = array();
            foreach($goods_list as $key=>$goods){
                $goods['practical_num'] = get_queue_goods_stock($goods['goods_id'],$wid);
                $goods_info = $this->checkGoodsIsPresell($goods,$is_tomorrow,$wid);
                if($goods_info['is_presell']==1){
                    $goods_stock = $goods_info['goods_stock'];
                }else{
                    $goods_stock = $goods['practical_num'];
                }

                if($goods_stock===false || ($goods_stock!==false && $goods['goods_number']>$goods_stock)){
                    $out_stock_goods[] = $goods;
                }else{
                    $goods['goods_stock'] = $goods_stock;
                    $goods['is_presell'] = $goods_info['is_presell'];
                    $goods_in_stock[] = $goods;
                }
            }

            if(!empty($out_stock_goods)){
                $goods_name = array();
                foreach ($out_stock_goods as $out_key=>$out_goods){
                    $goods_name[] = $out_goods['goods_name'];
                }
                $goods_name_str = implode(',',$goods_name);
                throw new HttpException('500','商品（'.$goods_name_str.'）库存不足，提交订单失败',1,$out_stock_goods);
            }else{
                //如果现售商品，且库存足够，则减去对应的库存
                foreach($goods_in_stock as $k=>$v){
                    if($v['is_presell']==0){
                        $goods_stock_new = get_queue_goods_stock($v['goods_id'],$wid);
                        $num = $goods_stock_new-$v['goods_number'];
                        set_queue_goods_stock($v['goods_id'],$wid,$num);
                    }
                }
            }
        }else{
            throw new NotFoundHttpException('500',"订单中没有商品");
        }
    }

    /**
     * 获取商品是否预售以及虚拟库存
     * @param $goods
     * @param $is_tomorrow
     * @param $wid
     * @return mixed
     */
    public function checkGoodsIsPresell($goods, $is_tomorrow, $wid)
    {
        if ($goods['practical_num'] - config('shidexian.rest_goods_number') >= $goods['goods_number']) {
            if ($goods['is_auto_morrow_presell'] && $is_tomorrow) {
                $goods_stock = $this->goodsRepository->getGoodsVirtualStock($goods['goods_id'], $wid);
                $goods['goods_stock'] = $goods_stock;
                $goods['is_presell'] = 1;
            } else {
                $goods['is_presell'] = 0;
            }
        } else {
            $goods_stock = $this->goodsRepository->getGoodsVirtualStock($goods['goods_id'], $wid);
            $goods['goods_stock'] = $goods_stock;
            $goods['is_presell'] = 1;
        }

        return $goods;
    }

    /**
     * 二维数组处理后商品数据
     * @author Jerry
     * @param array $goods
     * @return array
     */
    public function formatGoodsTransformList(array $goods)
    {
        if (empty($goods)) {
            return [];
        }

        foreach ($goods as $key => $value) {
            $goods[$key] = $this->formatGoodsTransform($value);
        }

        return $goods;
    }

    /**
     * 返回处理后商品数据
     * @author Jerry
     * @param array $goods
     * @return array
     */
    public function formatGoodsTransform(array $goods)
    {
        if (empty($goods)) {
            return [];
        }

        if ($goods['is_presell'] == 1) {
            $goods['is_presell'] = ($goods['practical_num'] > 0) ? 0 : 1;
        }

        if ($goods['is_presell'] == 0) {
            $practical_num = $goods['practical_num'] - config('shidexian.rest_goods_number');

            if ($practical_num <= 0) {
                $practical_num = 0;
            }

//				现售商品使用实际库存
            $goods['goods_number'] = $practical_num;
        }

        $goods['preselltimeres'] = [
            'delivery_time' =>  '',
        ];

        if ($goods['is_presell']) {
            if ($goods['delivery_type'] == 1) {
                $shipingTime = $this->checkGoodsPreSaleTimeCount($goods['goods_id']);
                if ($shipingTime) {
                    $time = time();
                    $shippingTime = $this->checkGoodsPreSaleTime($goods['goods_id'], $time);

                    if ($shippingTime) {
                        $goods['preselltimeres'] = $shippingTime;
                    }
                }
            }

            if($goods['delivery_type'] == 2) {
                if ($goods['delivery_cycle']>=0) {
                    $gmd = local_date('Y-m-d', gm_time());

                    $goodsPresellTime = local_date('Y-m-d H:i:s', local_str_to_time($gmd . ' +' . $goods['delivery_cycle'] . ' day ' . config('shidexian.default_presell_time_h')));
                    $goods['preselltimeres'] = array(
                        'delivery_time' => $goodsPresellTime
                    );
                }
            }
        }

        if ($goods['goods_number'] == 0) {
            $goods['is_book_goods'] = $this->isBookGoods($goods['goods_id']);
        }

        $goods = $this->promoteService->formatPromoteData($goods);

        return $goods;
    }

    /**
     * 检查该订单商品是否在发货时间分段内
     * @author Jerry
     * @param int $goodsId
     * @param string $payTime
     * @return bool
     */
    protected function checkGoodsPreSaleTime(int $goodsId, string $payTime)
    {
        $result = $this->goodsPresellTimeRepository->findGoodsPreSaleTimeByGoodsId($goodsId, $payTime);

        if (! $result) {
            return false;
        }

        return $result;
    }

    /**
     * 检查预售商品是否设置发货配送时间
     * @author Jerry
     * @param int $goodsId
     * @return bool
     */
    protected function checkGoodsPreSaleTimeCount(int $goodsId)
    {
        $count = $this->goodsPresellTimeRepository->findGoodsShippingPreSaleTimeCountByGoodsId($goodsId);

        if ($count) {
            return true;
        }

        return false;
    }

    /**
     * 判断是否已订阅
     * @author Jerry
     * @param int $goodsId
     * @return bool
     */
    protected function isBookGoods(int $goodsId)
    {
        $userId = 3060;

        return $this->goodsBookRepository->findGoodsBookCountByGoodsId($goodsId, $userId);
    }

    /**
     * 根据用户等级获取商品价格
     * @author yangzhic
     * @param int $goodsId
     * @param int $userRank
     * @return string
     */
    public function getGoodsPrice(int $goodsId,int $userRank=2)
    {
        $price = Cache::get('user_price_'.$goodsId.'_'.$userRank);
        if(empty($price)){
            $goods_info = $this->goodsRepository->getGoodsPrice($goodsId,$userRank);
            if(!empty($goods_info->user_price)){
                $price = $goods_info->user_price;
            }elseif(!empty($goods_info->discount)){
                $price = $goods_info->shop_price*$goods_info->discount/100;
            }else{
                $price = $goods_info->shop_price;
            }

            if(!empty($price)){
                Cache::put('user_price_'.$goodsId.'_'.$userRank,$price,60);
            }
        }

        return get_price($price);
    }

    /**
     * 根据用户返回商品价格
     * @author yangzhic
     * @param int $goodsId
     * @param int $userId
     * @return string
     */
    public function getGoodsPriceByUserId(int $goodsId,int $userId){
        if(empty($userId)){
            $price = $this->getGoodsPrice($goodsId,1);
        }else{
            $userRank = $this->usersRepository->getUserRankByUid($userId);
            $price = $this->getGoodsPrice($goodsId,$userRank);
        }

        return $price;
    }

    /**
     * 获取购物袋商品信息
     * @author yangzhic
     * @param String $shoppingBag
     * @param int $userId
     * @param $wid
     * @return array
     */
    public function getShoppingBagById(String $shoppingBag,int $userId,$wid){
        $bag_info = [];
        $bag_goods_list = [];
        $bag_total_price = 0;
        $bag_out_stock_goods_list = [];
        if(!empty($shoppingBag)){
            $shoppingBag = str_replace('&quot;','"',$shoppingBag);
            $shoppingBag = json_decode($shoppingBag,true);

            $bag_num_list = [];
            $goods_id_list = [];
            foreach($shoppingBag as $key=>$val){
                if(!empty($val['goods_id']) && !empty($val['goods_number'])){
                    $bag_num_list[$val['goods_id']] = $val['goods_number'];
                    $goods_id_list[] = $val['goods_id'];
                }
            }

            $goods_list = $this->goodsRepository->getByIdsFromWid($goods_id_list,$wid);

            foreach ($goods_list as $key=>$goods_info){
                if(!empty($goods_info) && $goods_info['practical_num']>0){
                    $res = [];
                    $res['user_id'] = $userId;
                    $res['goods_id'] = $goods_info['goods_id'];
                    $res['goods_name'] = $goods_info['goods_name'];
                    $res['goods_sn'] = $goods_info['goods_sn'];
                    $res['product_id'] = 0;
                    $res['goods_number'] = $bag_num_list[$goods_info['goods_id']];
                    $res['market_price'] = $goods_info['shop_price'];
                    $res['goods_price'] = $this->getGoodsPriceByUserId($goods_info['goods_id'], $userId);
                    $res['goods_discount'] = 0;
                    $res['goods_attr'] = "";
                    $res['is_real'] = 1;
                    $res['extension_code'] = "";
                    $res['parent_id'] = 0;
                    $res['is_gift'] = 0;
                    $res['is_quota'] = 0;
                    $res['is_presell'] = 0;
                    $res['giving'] = 0;
                    $res['rec_type'] = 0;
                    $res['is_shipping'] = 0;
                    $res['can_handsel'] = 0;
                    $res['goods_attr_id'] = "";
                    $res['act_id'] = 0;
                    $res['expiration_date'] = 0;
                    $res['goods_discount'] = 0;
                    $res['is_cashier'] = 0;
                    $res['cashier_id'] = "";
                    $res['use_bonus'] = 0;

                    $bag_total_price+=$res['goods_price']*$res['goods_number'];

                    $bag_goods_list[] = $res;
                }else{
                    $bag_out_stock_goods_list[] = $goods_info;
                }
            }
        }

        $bag_info['goods_list'] = $bag_goods_list;
        $bag_info['total_price'] = round($bag_total_price,2);
        $bag_info['out_stock_goods_list'] = $bag_out_stock_goods_list;

        return $bag_info;
    }


    /**
     * 获取购物袋列表
     * @author yangzhic
     * @param $userId
     * @param $wid
     * @return array
     */
    public function getShoppingBag(int $userId, int $wid){
        $bag_list = [];
        $shopping_bag_config = config('shidexian.shopping_bag_config');
        if($shopping_bag_config['status']==1 && !empty($shopping_bag_config['goods_id'])){
            $goods_list = $this->goodsRepository->getByIdsFromWid($shopping_bag_config['goods_id'],$wid);
            foreach ($goods_list as $key=>$goods_info){
                if(!empty($goods_info) && $goods_info->practical_num>0){
                    $res = [];
                    $res['goods_id'] = $goods_info->goods_id;
                    $res['goods_name'] = $goods_info->goods_name;
                    $res['goods_sn'] = $goods_info->goods_sn;
                    $res['goods_number'] = $goods_info->practical_num;
                    $res['goods_price'] = $this->getGoodsPriceByUserId($goods_info->goods_id, $userId);
                    $bag_list[] = $res;
                }
            }
        }

        return $bag_list;
    }
}